package foo.bar.wiki.web.action.user;

import foo.bar.wiki.web.action.BaseActionBean;
import foo.bar.wiki.web.extension.UserTypeConverter;
import foo.bar.wiki.domain.User;
import foo.bar.wiki.domain.Role;
import foo.bar.wiki.services.UserService;
import foo.bar.wiki.services.exception.BusinessLogicExecution;
import foo.bar.wiki.security.RoleType;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.SimpleMessage;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.EnumeratedTypeConverter;
import net.sourceforge.stripes.validation.DateTypeConverter;
import net.sourceforge.stripes.integration.spring.SpringBean;

import java.util.Set;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author tmjee
 * @version $Date$ $Id$
 */
public class EditUserActionBean extends BaseActionBean {

    private static final Log LOG = LogFactory.getLog(EditUserActionBean.class);

    public static final String VIEW = "/user/editUser.jsp";


    @Validate(converter = EnumeratedTypeConverter.class, on={"save"})
    private Set<RoleType> roles;

    private UserService userService;

    @Validate(converter= UserTypeConverter.class)
    @ValidateNestedProperties({
      @Validate(field="email", trim=true, required=true, on={"save"}),
      @Validate(field="expiryDate", converter = DateTypeConverter.class, on={"save"})
    })
    private User user;



    public Resolution view() {
        return new ForwardResolution(generateThemePath(VIEW));
    }

    public Resolution save() throws Throwable {
        return handleBusinessLogicException(new BusinessLogicExecution(){
            public Resolution execute() throws Throwable {
                // delete the roles first. GAE doesn't auto remove the relationship but repopulate them back
                // unlike relational db's persistence provider, which will auto remove the relationship when
                // the transaction ends. 
                Set<Role> toBeDeletedRoles = user.updateRole(roles);
                userService.deleteRole(new ArrayList<Role>(toBeDeletedRoles));

                user = userService.updateUser(user);
                getContext().getMessages().add(new SimpleMessage("User "+user.getUsername()+" updated"));
                return new RedirectResolution(EditUserActionBean.class, "view")
                                                    .addParameter("user", user.getId());        
            }
        });
    }


    @SpringBean("userService")
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Set<RoleType> getRoles() {
        return roles;
    }

    public void setRoles(Set<RoleType> roles) {
        this.roles = roles;
    }
}